﻿using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using Caliburn.Micro;
using DomusDotNet.Sbm.Client.SL4.Infrastructure;
using DomusDotNet.Sbm.Client.SL4.WCFServices;
using System;

namespace DomusDotNet.Sbm.Client.SL4.ViewModels
{
	[Export]
	[PartCreationPolicy(CreationPolicy.NonShared)]
	public class SearchViewModel : Screen, IHasBusyState, IStoreInHistory
	{

		Func<BookViewModel> bookViewModelFactory;
		IShell shell;
		IWindowManager windowManager;
		[ImportingConstructor]
		public SearchViewModel(IShell shell, IWindowManager windowManager, Func<BookViewModel> bookViewModelFactory)
		{
			this.shell = shell;
			this.windowManager = windowManager;
			this.bookViewModelFactory = bookViewModelFactory;

			BusyState = new BusyState();
			Books = new BindableCollection<BookBase>();
			Clear();
		}

		public SearchBooksRequest Criteria { get; set; }
		public BindableCollection<BookBase> Books { get; set; }
		public string ErrorMessage { get; set; }

		public void Clear()
		{
			if (Criteria != null) Criteria.PropertyChanged -= Criteria_PropertyChanged;

			Criteria = new SearchBooksRequest();
			Criteria.PropertyChanged += Criteria_PropertyChanged;

			Books.Clear();
		}

		void Criteria_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
		{
			ErrorMessage = string.Empty;
		}



		public IEnumerable<IResult> Search()
		{
			using (BusyState.Set())
			{
				ErrorMessage = string.Empty;
				var search = CallService.For(Criteria);
				yield return search;

				var response = search.GetResponse<SearchBooksResponse>();

				if (!response.Result)
				{
					ErrorMessage = response.Errors.GetStringMessage();
				}
				else
				{
					this.Books.Clear();
					if (response.Books.Count == 0)
					{
						ErrorMessage = "Nessun risultato trovato per i criteri correnti";
					}
					else if (response.Books.Count == 1)
					{
						ShowBook(response.Books.Single());
					}
					else
					{

						this.Books.AddRange(response.Books);
					}
				}
			}
		}

		public bool CanShowBook(BookBase book)
		{
			return book != null;
		}
		public void ShowBook(BookBase book)
		{
			var vm = bookViewModelFactory();
			vm.Book = book;
			shell.ActivateItem(vm);
		}
		public void ShowBookDialog(BookBase book)
		{
			var vm = bookViewModelFactory();
			vm.Book = book;
			windowManager.ShowDialog(vm);
		}

		public BusyState BusyState { get; set; }



		public class Factory
		{
			[Export(typeof(Func<SearchViewModel>))]
			public static SearchViewModel Create() { return IoC.Get<SearchViewModel>(); }
		}


	}

}
